/*
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.errorprone;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Commandline.Argument;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.LoaderUtils;
/**
* Ant component to launch an external javac with error-prone enabled.
*/
public class ErrorProneExternalCompilerAdapter extends DefaultCompilerAdapter {
private Path classpath;
private String memoryStackSize;
private List<Argument> jvmArgs = new ArrayList<Argument>();
public void setClasspath(Path classpath) {
this.classpath = classpath;
}
public Path createClasspath() {
if (classpath == null) {
classpath = new Path(getProject());
}
return classpath.createPath();
}
public void setClasspathRef(Reference r) {
createClasspath().setRefid(r);
}
public void setMemoryStackSize(String memoryStackSize) {
this.memoryStackSize = memoryStackSize;
}
public Argument createJvmArg() {
Argument arg = new Argument();
jvmArgs.add(arg);
return arg;
}
@Override
public boolean execute() throws BuildException {
if (getJavac().isForkedJavac()) {
attributes.log("Using external Error Prone compiler", Project.MSG_VERBOSE);
Commandline cmd = new Commandline();
cmd.setExecutable(JavaEnvUtils.getJdkExecutable("java"));
if (memoryStackSize != null) {
cmd.createArgument().setValue("-Xss" + memoryStackSize);
}
String memoryParameterPrefix = "-X";
if (memoryInitialSize != null) {
cmd.createArgument().setValue(memoryParameterPrefix + "ms" + this.memoryInitialSize);
// Prevent setupModernJavacCommandlineSwitches() from doing it also
memoryInitialSize = null;
}
if (memoryMaximumSize != null) {
cmd.createArgument().setValue(memoryParameterPrefix + "mx" + this.memoryMaximumSize);
// Prevent setupModernJavacCommandlineSwitches() from doing it also
memoryMaximumSize = null;
}
for (Argument arg : jvmArgs) {
for (String part : arg.getParts()) {
cmd.createArgument().setValue(part);
}
}
Path bootclasspath = new Path(getProject());
addResourceSource(bootclasspath, "com/google/errorprone/ErrorProneExternalCompilerAdapter.class");
cmd.createArgument().setValue("-Xbootclasspath/p:" + bootclasspath);
if (classpath != null) {
cmd.createArgument().setValue("-classpath");
cmd.createArgument().setPath(classpath);
}
cmd.createArgument().setValue(ErrorProneCompiler.class.getName());
setupModernJavacCommandlineSwitches(cmd);
int firstFile = cmd.size();
logAndAddFilesToCompile(cmd);
return executeExternalCompile(cmd.getCommandline(), firstFile, true) == 0;
} else {
attributes.log("You must set fork=\"yes\" to use the external Error Prone compiler",
Project.MSG_ERR);
return false;
}
}
private void addResourceSource(Path classpath, String resource) {
final File f = LoaderUtils.getResourceSource(
ErrorProneExternalCompilerAdapter.class.getClassLoader(),
resource);
if (f != null) {
attributes.log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
classpath.createPath().setLocation(f);
} else {
attributes.log("Couldn't find " + resource, Project.MSG_DEBUG);
}
}
}